package com.novak.rss.reader; 

import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

public class RSSHandler extends DefaultHandler
{ 
  static final int TYPE_UNKNOWN = 0;
  static final int TYPE_RSS = 1;
  static final int TYPE_ATOM = 2;
  private int type = TYPE_UNKNOWN; 
  
  private static boolean inItem = false;
  private static boolean inEntry = false;
  
  private static final String NODE_RSS_ITEM = "item";
  private static final String NODE_RSS_TITLE = "title";
  private static final String NODE_RSS_DESCRIPTION = "description";
  private static final String NODE_RSS_LINK = "link";
  private static final String NODE_RSS_PUBDATE = "pubDate";
  
  private static final String NODE_ATOM_ENTRY = "title";
  private static final String NODE_ATOM_TITLE = "title";
  private static final String NODE_ATOM_LINK = "link";
  private static final String NODE_ATOM_CONTENT = "content";
  private static final String NODE_ATOM_PUBLISHED = "published";
  private List<NewsItem> li;
  private NewsItem newsItem;
  private ChannelInfo chnInfo;
  private StringBuffer buf=new StringBuffer();
  
  private boolean firstElement = true;
  public List<NewsItem> getParsedData()
  { 
    return li; 
  }
  public ChannelInfo getRssChannel()
  { 
    return chnInfo; 
  }
  @Override 
  public void startDocument() throws SAXException
  { 
    li = new ArrayList<NewsItem>(); 
  } 
  @Override 
  public void endDocument() throws SAXException
  {
  } 
  @Override 
  public void startElement(String namespaceURI, String localName, 
               String qName, Attributes atts) throws SAXException
  { 
    
    if(firstElement){
      if("rss".equalsIgnoreCase(localName)){
        type = TYPE_RSS;
        chnInfo = new ChannelInfo();
      }else if("feed".equalsIgnoreCase(localName)){
        type = TYPE_ATOM;
        chnInfo = new ChannelInfo();
      }else{
        type = TYPE_UNKNOWN;
        throw new SAXException("Unknown type '<" + localName + ">'.");
      }
      firstElement = false;
      return;
    }
    if(type==TYPE_RSS){
      if(NODE_RSS_ITEM.equalsIgnoreCase(localName)){
        inItem = true;
        newsItem = new NewsItem();
        return;
      }
     
    }else if(type==TYPE_ATOM){
      if(NODE_ATOM_ENTRY.equalsIgnoreCase(localName)){
        inEntry = true;
        newsItem = new NewsItem();
        return;
      }
    }
    buf.setLength(0);
  }
  @Override 
  public void endElement(String namespaceURI, String localName,
                         String qName) throws SAXException
  { 

    if(type==TYPE_RSS){
      if(NODE_RSS_TITLE.equalsIgnoreCase(localName)){
        if(inItem){
          this.newsItem.setTitle(buf.toString().trim());
        }else{
          this.chnInfo.setTitle(buf.toString().trim());
        }
      //  buf.setLength(0);
        return;
      }
      if(NODE_RSS_DESCRIPTION.equalsIgnoreCase(localName)){
        if(inItem){
         this.newsItem.setDesc(buf.toString().trim()); 
        }else{
          this.chnInfo.setDescription(buf.toString().trim());
        }
     //   buf.setLength(0);
        return;
      }
      if(NODE_RSS_LINK.equalsIgnoreCase(localName)){
        if(inItem){
          this.newsItem.setUrl(buf.toString().trim());
        }else{
          this.chnInfo.setUrl(buf.toString().trim());
        }
    //    buf.setLength(0);
        return;
      }
      if(NODE_RSS_PUBDATE.equalsIgnoreCase(localName)){
        if(inItem){
          this.newsItem.setDate(buf.toString().trim());
        }else{
          this.chnInfo.setDate(buf.toString().trim());
        }
      //  buf.setLength(0);
        return;
      }
      if(NODE_RSS_ITEM.equalsIgnoreCase(localName)){
        li.add(this.newsItem);
        inItem = false;
     //   buf.setLength(0);
        return;
      }
    }else if(type==TYPE_ATOM){
      //TODO implement this section
    }
   
  } 
  @Override 
  public void characters(char ch[], int start, int length)
  { 
    buf.append(ch,start,length);
  } 
}

